package org.lemon.cla.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.lemon.cla.enums.HttpStatusEnum;
import org.lemon.cla.dto.response.ResponseResult;
import org.lemon.cla.dto.request.ClubActivityCreateRequest;
import org.lemon.cla.dto.request.ClubActivityUpdateRequest;
import org.lemon.cla.dto.request.ClubActivitySearchRequest;
import org.lemon.cla.pojo.ClubActivity;
import org.lemon.cla.pojo.User; // 导入 User 实体
import org.lemon.cla.pojo.Club; // 导入 Club 实体
import org.lemon.cla.vo.ClubActivityVo; // 导入 ClubActivityVo
import org.lemon.cla.service.IClubActivityService;
import org.lemon.cla.service.IUserService; // 导入 IUserService
import org.lemon.cla.service.IClubService; // 导入 IClubService
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;

import java.time.LocalDateTime;
import java.util.Optional; // 导入Optional

import org.lemon.cla.exception.BusinessException; // 导入自定义业务异常

@RestController
@RequestMapping("/api/club-activities")
@Tag(name = "社团活动管理", description = "提供社团活动信息的 CRUD 和查询接口")
public class ClubActivityController {

    @Autowired
    private IClubActivityService clubActivityService;

    @Autowired
    private IUserService userService; // 注入 IUserService
    @Autowired
    private IClubService clubService; // 注入 IClubService

    @Operation(summary = "获取所有社团活动", description = "分页获取所有社团活动列表，包含组织者信息")
    @GetMapping
    public ResponseResult<IPage<ClubActivityVo>> getAllClubActivities(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
        Page<ClubActivityVo> page = new Page<>(pageNum, pageSize);
        IPage<ClubActivityVo> activityPage = clubActivityService.getAllClubActivitiesVo(page);
        return ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), activityPage);
    }

    @Operation(summary = "根据ID获取社团活动", description = "根据活动ID获取社团活动详情，包含组织者信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "成功获取活动"),
            @ApiResponse(responseCode = "404", description = "活动未找到")
    })
    @GetMapping("/{id}")
    public ResponseResult<ClubActivityVo> getClubActivityById(
            @Parameter(description = "活动ID", required = true, example = "1") @PathVariable Long id) {
        // 使用Optional简化null检查，如果未找到则抛出业务异常
        return Optional.ofNullable(clubActivityService.getClubActivityVoById(id))
                .map(activityVo -> ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), activityVo))
                .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "活动未找到。")); // 抛出BusinessException
    }

    @Operation(summary = "创建新社团活动", description = "创建一个新的社团活动记录 (**活动ID自增，参与人数默认0，所属社团及组织者不能是逻辑删除状态**)")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "201", description = "活动创建成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误 (如校验失败)"),
            @ApiResponse(responseCode = "404", description = "所属社团或组织者用户不存在或已逻辑删除"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @PostMapping
    @PreAuthorize("hasRole('管理员')") // 只有拥有 'ROLE_管理员' 角色的用户才能访问
    public ResponseResult<ClubActivity> createClubActivity(
            @Parameter(description = "社团活动创建请求对象", required = true)
            @RequestBody @Valid ClubActivityCreateRequest request) {

        // 1. 业务校验：所属社团是否存在且未被逻辑删除，如果不存在则抛出业务异常
        Optional.ofNullable(clubService.getById(request.getClubId()))
                .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "社团活动创建失败：所属社团不存在或已逻辑删除。"));

        // 2. 业务校验：组织者用户是否存在且未被逻辑删除，如果不存在则抛出业务异常
        Optional.ofNullable(userService.getById(request.getOrganizerId().intValue()))
                .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "社团活动创建失败：组织者用户不存在或已逻辑删除。"));

        ClubActivity clubActivity = new ClubActivity();
        BeanUtils.copyProperties(request, clubActivity);

        clubActivity.setParticipantCount(0); // Default participant count to 0

        boolean success = clubActivityService.save(clubActivity);
        if (!success) { // 如果保存操作返回false但没有异常抛出
            throw new BusinessException(HttpStatusEnum.BAD_REQUEST.getCode(), "社团活动创建失败，请稍后重试。"); // 抛出BusinessException
        }
        return ResponseResult.success(HttpStatusEnum.CREATED.getCode(), HttpStatusEnum.CREATED.getMessage(), clubActivity);
    }

    @Operation(summary = "更新社团活动信息", description = "根据活动ID更新社团活动信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "活动更新成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "404", description = "活动未找到"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @PutMapping("/{id}")
    @PreAuthorize("hasRole('管理员')") // 只有拥有 'ROLE_管理员' 角色的用户才能访问
    public ResponseResult<ClubActivity> updateClubActivity(
            @Parameter(description = "活动ID", required = true, example = "1") @PathVariable Long id,
            @Parameter(description = "更新后的社团活动对象", required = true) @RequestBody @Valid ClubActivityUpdateRequest request) {

        // 校验活动是否存在，如果不存在则抛出业务异常
        ClubActivity existingActivity = Optional.ofNullable(clubActivityService.getById(id))
                .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "活动未找到。"));

        // 校验新的所属社团是否存在且未被逻辑删除 (如果 clubId 被修改)
        Optional.ofNullable(request.getClubId())
                .filter(newClubId -> !newClubId.equals(existingActivity.getClubId())) // 只有当 clubId 实际改变时才校验
                .ifPresent(newClubId -> Optional.ofNullable(clubService.getById(newClubId))
                        .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "更新失败：新的所属社团不存在或已逻辑删除。")));

        // 校验新的组织者是否存在且未被逻辑删除 (如果 organizerId 被修改)
        Optional.ofNullable(request.getOrganizerId())
                .filter(newOrgId -> !newOrgId.equals(existingActivity.getOrganizerId())) // 只有当 organizerId 实际改变时才校验
                .ifPresent(newOrgId -> Optional.ofNullable(userService.getById(newOrgId.intValue()))
                        .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "更新失败：新的组织者用户不存在或已逻辑删除。")));

        BeanUtils.copyProperties(request, existingActivity);

        boolean success = clubActivityService.updateById(existingActivity);
        if (!success) { // 如果更新返回false
            throw new BusinessException(HttpStatusEnum.BAD_REQUEST.getCode(), "社团活动更新失败，请稍后重试。"); // 抛出BusinessException
        }
        return ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), existingActivity);
    }

    @Operation(summary = "删除社团活动", description = "根据活动ID删除社团活动。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "204", description = "活动删除成功"),
            @ApiResponse(responseCode = "404", description = "活动未找到"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('管理员')")
    public ResponseResult<Void> deleteClubActivity(
            @Parameter(description = "活动ID", required = true, example = "1") @PathVariable Long id) {
        boolean success = clubActivityService.removeById(id);
        if (!success) { // 如果删除返回false
            throw new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "活动未找到或删除失败。"); // 抛出BusinessException
        }
        return ResponseResult.success(HttpStatusEnum.NO_CONTENT.getCode(), HttpStatusEnum.NO_CONTENT.getMessage(), null);
    }

    @Operation(summary = "模糊查询社团活动(查询首选)", description = "根据多条件进行模糊查询，包括所属社团ID、活动名称、内容、地点、时间范围、组织者ID和参与人数范围，返回包含组织者信息的视图对象")
    @PostMapping("/search")
    public ResponseResult<IPage<ClubActivityVo>> searchClubActivities(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "社团活动查询请求对象 (可选，用于筛选)",
                    required = false,
                    content = @Content(schema = @Schema(implementation = ClubActivitySearchRequest.class))
            ) @org.springframework.web.bind.annotation.RequestBody ClubActivitySearchRequest request) {

        Page<ClubActivityVo> page = new Page<>(pageNum, pageSize);

        // 使用Optional简化，确保request总是一个非null的实例
        request = Optional.ofNullable(request).orElseGet(ClubActivitySearchRequest::new);

        IPage<ClubActivityVo> resultPage = clubActivityService.searchClubActivitiesByConditions(page, request);

        return ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), resultPage);
    }
}
